package com.zenithmind.library.service.base;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zenithmind.common.base.BaseEntity;
import com.zenithmind.common.result.Result;
import com.zenithmind.common.result.ResultCode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;

import java.time.LocalDateTime;
import java.util.List;

/**
 * 图书馆服务基类
 * 遵循里氏替换原则：子类可以替换父类而不影响程序的正确性
 * 遵循单一职责原则：只负责通用的CRUD操作
 * 
 * @author ZenithMind
 * @since 2024-06-14
 */
@Slf4j
public abstract class BaseLibraryService<M extends BaseMapper<T>, T extends BaseEntity> 
        extends ServiceImpl<M, T> {

    /**
     * 创建实体的通用方法
     * 
     * @param entity 实体对象
     * @return 创建结果
     */
    protected Result<T> createEntity(T entity) {
        try {
            // 设置创建时间和更新时间
            entity.setCreateTime(LocalDateTime.now());
            entity.setUpdateTime(LocalDateTime.now());
            
            // 执行创建前的验证
            Result<Void> validationResult = validateBeforeCreate(entity);
            if (!validationResult.isSuccess()) {
                return Result.fail(validationResult.getCode(), validationResult.getMsg(), null);
            }
            
            // 执行创建前的处理
            beforeCreate(entity);
            
            // 保存实体
            boolean saved = save(entity);
            if (!saved) {
                return Result.fail(ResultCode.FAIL.getCode(), "创建失败", null);
            }
            
            // 执行创建后的处理
            afterCreate(entity);
            
            return Result.success(entity);
        } catch (Exception e) {
            log.error("创建实体失败", e);
            return Result.fail(ResultCode.FAIL.getCode(), "创建失败：" + e.getMessage(), null);
        }
    }

    /**
     * 更新实体的通用方法
     * 
     * @param id 实体ID
     * @param updateData 更新数据
     * @return 更新结果
     */
    protected Result<T> updateEntity(String id, Object updateData) {
        try {
            // 查询现有实体
            T existingEntity = getById(id);
            if (existingEntity == null) {
                return Result.fail(ResultCode.NOT_FOUND.getCode(), "实体不存在", null);
            }
            
            // 执行更新前的验证
            Result<Void> validationResult = validateBeforeUpdate(existingEntity, updateData);
            if (!validationResult.isSuccess()) {
                return Result.fail(validationResult.getCode(), validationResult.getMsg(), null);
            }
            
            // 复制属性
            BeanUtils.copyProperties(updateData, existingEntity);
            existingEntity.setUpdateTime(LocalDateTime.now());
            
            // 执行更新前的处理
            beforeUpdate(existingEntity, updateData);
            
            // 更新实体
            boolean updated = updateById(existingEntity);
            if (!updated) {
                return Result.fail(ResultCode.FAIL.getCode(), "更新失败", null);
            }
            
            // 执行更新后的处理
            afterUpdate(existingEntity, updateData);
            
            return Result.success(existingEntity);
        } catch (Exception e) {
            log.error("更新实体失败，ID：{}", id, e);
            return Result.fail(ResultCode.FAIL.getCode(), "更新失败：" + e.getMessage(), null);
        }
    }

    /**
     * 删除实体的通用方法
     * 
     * @param id 实体ID
     * @return 删除结果
     */
    protected Result<Void> deleteEntity(String id) {
        try {
            // 查询现有实体
            T existingEntity = getById(id);
            if (existingEntity == null) {
                return Result.fail(ResultCode.NOT_FOUND.getCode(), "实体不存在", null);
            }
            
            // 执行删除前的验证
            Result<Void> validationResult = validateBeforeDelete(existingEntity);
            if (!validationResult.isSuccess()) {
                return Result.fail(validationResult.getCode(), validationResult.getMsg(), null);
            }
            
            // 执行删除前的处理
            beforeDelete(existingEntity);
            
            // 删除实体
            boolean deleted = removeById(id);
            if (!deleted) {
                return Result.fail(ResultCode.FAIL.getCode(), "删除失败", null);
            }
            
            // 执行删除后的处理
            afterDelete(existingEntity);
            
            return Result.success();
        } catch (Exception e) {
            log.error("删除实体失败，ID：{}", id, e);
            return Result.fail(ResultCode.FAIL.getCode(), "删除失败：" + e.getMessage(), null);
        }
    }

    /**
     * 批量删除实体的通用方法
     * 
     * @param ids 实体ID列表
     * @return 删除结果
     */
    protected Result<Void> batchDeleteEntities(List<String> ids) {
        try {
            for (String id : ids) {
                Result<Void> result = deleteEntity(id);
                if (!result.isSuccess()) {
                    return result;
                }
            }
            return Result.success();
        } catch (Exception e) {
            log.error("批量删除实体失败", e);
            return Result.fail(ResultCode.FAIL.getCode(), "批量删除失败：" + e.getMessage(), null);
        }
    }

    // 钩子方法，子类可以重写以实现特定的业务逻辑

    /**
     * 创建前验证
     */
    protected Result<Void> validateBeforeCreate(T entity) {
        return Result.success();
    }

    /**
     * 创建前处理
     */
    protected void beforeCreate(T entity) {
        // 默认空实现
    }

    /**
     * 创建后处理
     */
    protected void afterCreate(T entity) {
        // 默认空实现
    }

    /**
     * 更新前验证
     */
    protected Result<Void> validateBeforeUpdate(T existingEntity, Object updateData) {
        return Result.success();
    }

    /**
     * 更新前处理
     */
    protected void beforeUpdate(T existingEntity, Object updateData) {
        // 默认空实现
    }

    /**
     * 更新后处理
     */
    protected void afterUpdate(T existingEntity, Object updateData) {
        // 默认空实现
    }

    /**
     * 删除前验证
     */
    protected Result<Void> validateBeforeDelete(T entity) {
        return Result.success();
    }

    /**
     * 删除前处理
     */
    protected void beforeDelete(T entity) {
        // 默认空实现
    }

    /**
     * 删除后处理
     */
    protected void afterDelete(T entity) {
        // 默认空实现
    }
}
